use std::fs::File;
use std::io::{self, prelude::*, BufReader};

struct Toboggan {
    slope : f64,
    trees : u32,
}

struct Point(f64, f64);

struct Ride {
    toboggan      : Toboggan, 
    current_point : Point,
}


fn main() -> io::Result<()>{

    let input = File::open("input.txt")?;
    let reader = BufReader::new(input);
    let mut rides = Vec::new(); 
    let mut tree_number = 0;
    let mut y_coord = 0;
    let mut x_coord = 0;
    let mut pattern_width = 0;
    let tree: char = '#';
    
    rides.push(Ride { toboggan      : Toboggan { slope : 1.0, trees : 0 },
                      current_point : Point (0.0, 0.0)});
    rides.push(Ride { toboggan      : Toboggan { slope : 3.0, trees : 0 },
                      current_point : Point (0.0, 0.0)});
    rides.push(Ride { toboggan      : Toboggan { slope : 5.0, trees : 0 },
                      current_point : Point (0.0, 0.0)});
    rides.push(Ride { toboggan      : Toboggan { slope : 7.0, trees : 0 },
                      current_point : Point (0.0, 0.0)});
    rides.push(Ride { toboggan      : Toboggan { slope : 0.5, trees : 0 },
                      current_point : Point (0.0, 0.0)});


    for line in reader.lines() {
        let str = line?;

        //Part 1:
        if y_coord == 0 {
            pattern_width = str.len();
        } else if str.chars().nth(x_coord % pattern_width).unwrap() == tree{
            tree_number += 1;
        }
        
        y_coord += 1;
        x_coord += 3;
        // Part 2:
        for ride in rides.iter_mut(){
            let current_x_coord = ride.current_point.0;
            if ride.current_point.1 != 0.0 // skip the start
                && current_x_coord.fract() == 0.0 
                && str.chars().nth((current_x_coord as usize) % pattern_width).unwrap() == tree { 
                ride.toboggan.trees += 1; 
            }
            ride.current_point.0 += ride.toboggan.slope;
            ride.current_point.1 += 1f64;
        }
    }

    println!("Part 1 toboggan  arrived at ({}, {}) coordinates. We encountered {} trees.", x_coord, y_coord, tree_number);    
    let mut i = 0;
    let mut part2_result = 1;
    for ride in &rides{
        i += 1;
        println!("Toboggan {} with slope {} arrived at ({}, {}) and encountered {} trees",
                 i,
                 ride.toboggan.slope,
                 ride.current_point.0,
                 ride.current_point.1,
                 ride.toboggan.trees);
        part2_result *= ride.toboggan.trees;
    }
    println!("Part 2 response is : {}", part2_result);
    Ok(())
}
